/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */
package jp.ize.ux.components;

// {{{ imports
#if flash9
import flash.display.MovieClip;
import flash.events.Event;
#elseif flash
import flash.MovieClip;
#end
import jp.ize.iwp.utils.ClassUtil;
// }}}
// {{{ enum Frame
enum Frame
{
	Index( index:Int );
	Label( label:String );
	Range( from:Frame, to:Frame );
	Draw( drawer:MovieClip->Void );
}
// }}}
// {{{ class UXResource
/** 
 * UXResource クラス<br>
 * デザイン描画に利用されるリソース情報です。<br>
 * 
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id: UXResource.hx 20 2009-02-04 08:23:19Z yimai.v $<br>
 */
class UXResource extends UXBasicComponent
{
	// {{{ properites
	/** 
	* Flash CS4 等で MovieClip を継承したクラスをリソースとして扱います。
	*/
	public var resource : Dynamic;

	/**
	* 状態名とムービークリップのフレーム番号、フレームラベル等を格納します。
	*/
	public var states : Hash<Frame>;

	// }}}
	// {{{ public function new( ?res:Dynamic ) : Void
	/**
	* コンストラクタ
	* Flash CS4 等で MovieClip を継承したクラスをリソースとして扱います。
	* 各フレームに状態のデザインを配置するようにします。
	* MovieClip.gotoAndStop によりデザイン状態の変更を管理します。
	* states に状態名とフレーム・インデックスを格納しておきます。
	* setState() で状態名を指定することでデザインの変更を行ないます。
	*
	* @param res: ムービークリップを内部リソースとして指定します。省略可能です。
	*/
	public function new( ?res:Dynamic ) : Void
	{
		super();
		if ( res==null ) res = new MovieClip();
		resource = res;
		addChild(resource);
		states = new Hash();
	}
	// }}}
	// {{{ public function create( classname:String ) : Void
	/**
	 * Flash CS4 等でシンボルを書き出したクラス名を指定してリソースのインスタンスを新たに作ります。
	 * 該当するシンボルが存在しなかった場合は、新規のムービークリップを代わりに作ります。
	 */
	public function create( classname:String ) : Void
	{
		if ( resource!=null ) {
			removeChild(resource);
		}
		resource = ClassUtil.getMovieClip(classname);
		addChild(resource);
	}
	// }}}
	// {{{ public function attach( res:Dynamic ) : Void
	/**
	 * Flash CS4 等でシンボルを書き出したクラス名を指定してリソースのインスタンスを設定します。
	 * new(), create() とは異なり、addChid() を行いません。
	 * すでに Display Tree に追加されたリソースを対象にします。
	 */
	public function attach( res:Dynamic ) : Void
	{
		if ( resource!=null ) {
			removeChild(resource);
		}
		resource = res;
	}
	// }}}
	// {{{ public function addState( statename:String, frame:Frame ) : Void
	/**
	* 状態名とそれに該当するデザインの配置されたムービークリップのフレーム番号を指定し状態を追加します。
	*/
	public function addState( statename:String, frame:Frame ) : Void
	{
		states.set(statename,frame);
	}

	// }}}
	// {{{ public function removeState( statename:String ) : Void
	/**
	* 状態名とそれに該当するデザインの配置されたムービークリップのフレーム番号を指定し状態を追加します。
	*/
	public function removeState( statename:String ) : Void
	{
		if ( states.exists(statename) ) {
			states.remove(statename);
		}
	}

	// }}}
	// {{{ public function setState( statename:String ) : Void
	/**
	* デザインを指定された状態に変更します。
	*/
	public function setState( statename:String ) : Void
	{
		if ( resource==null ) return;
		if ( states.exists(statename) ) {
			var frame = states.get(statename);
			switch ( frame ) {
				case Index(index):
					resource.gotoAndStop(index);
				case Label(label):
					resource.gotoAndStop(label);
				case Range(from,to):
					// {{{ case Range(from,to):
					var fromObj:Dynamic = null;
					switch ( from ) {
						case Index(index):
							resource.gotoAndPlay(index);
						case Label(label):
							resource.gotoAndPlay(label);
						default:
							// do nothing
					}
					var me = this;
					var onEnterFrame:Event->Void = null;
					onEnterFrame = function(e) {
						var flag:Bool = false;
						switch ( to ) {
							case Index(index):
								if ( me.resource.currentFrame==index ) {
									flag = true;
								}
							case Label(label):
								if ( me.resource.currentLabel==label ) {
									flag = true;
								}
							default:
								// do nothing
						}
						if ( flag ) {
							me.resource.stop();
							me.resource.removeEventListener( Event.ENTER_FRAME, onEnterFrame );
						}
					}
					resource.addEventListener( Event.ENTER_FRAME, onEnterFrame, false, 0, true );
					// }}}
				case Draw(drawer):
					drawer(resource);
			}
		}
	}

	// }}}
}
// }}}
